//------------------------------------------------------------------------
// Abstract: Define of class XFile
//
// Authoring: XiaoHanxiong
//
// Time: 2014.04.17
//
// Static test:
//
// Version history:
//		Ver_1.0	: 2014.04.17	XiaoHanxiong
//------------------------------------------------------------------------
#ifndef _Library_XFile_h_
#define _Library_XFile_h_

#include "Stdafx.h"


namespace Library
{
	enum _LIBRARY Encoding
	{
		Unvalid = 0x0,
		ANSI,
		UTF8,
		UnicodeBE,
		UnicodeLE
	};
	typedef Encoding ENCODING;

	class _LIBRARY XFile
	{
	public:
		// Constructor
		XFile();
		// Destructor
		~XFile();

	public:
		static bool ReNameFile(char* oldName, char* newName);

	public:
		// r:  Open a file only for read, the file must be exist
		// w:  Open a file only for write, if the file do not exist it will build a file, 
		//	   nor it will truncate the data
		// a:  Open a file only for write, if the file do not exist it will build a file, all of the data 
		//	   will be written at the end of the file
		// r+: Open a file for both read and write 
		// w+: Open a file for both read and write, if there are data in the file, it will be truncate,
		//	   if the file do not exist it will build a file
		// a+: Open a file for both read and write, if the file do not exist it will build a file, nor
		//	   all the data will be written at the end of the file

	
	public:
		// Open for read/write(ANSI Encoding)
		bool OpenA(char* fileName, Encoding type, const char* openMode = "r+");
		// Open a file for read/write(UTF8/UnicodeBE/UnicodeLE Encoding)
		bool OpenW(wchar_t* fileName, Encoding type, const wchar_t* openMode = _T("r+"));
		// Open a binary file
		bool OpenB(char* fileName, const char* openMode = "r+");
		// Close the file
		void Close();

	public:
		const static size_t Max_Text_size = 1024;
	
	/* Operation for text files */
	public:
		// Read the file(ANSI Encoding)
		void ReadLineA(string& str, size_t max_size);
		void ReadLineA(char* buffer, size_t buffer_size, size_t max_size);
		void ReadA(string& str, size_t max_size);
		void ReadA(char* buffer, size_t buffer_size, size_t max_size);
		// Read the file(UTF8/UnicodeBE/UnicodeLE Encoding)
		void ReadLineW(wstring& str, size_t max_size);
		void ReadLineW(wchar_t* buffer, size_t buffer_size, size_t max_size);
		void ReadW(wstring& str, size_t max_size);
		void ReadW(wchar_t* buffer, size_t buffer_size, size_t max_size);

		// Write the file(ANSI Encoding)
		void WriteA(string& str);
		void WriteA(char* buffer, size_t size);
		void WriteLineA(string& str);
		void WriteLineA(char* buffer, size_t size);
		// Write the file(UTF8/UnicodeBE/UnicodeLE Encoding)
		void WriteW(wstring& str);
		void WriteW(wchar_t* buffer, size_t size);
		void WriteLineW(wstring& str);
		void WriteLineW(wchar_t* buffer, size_t size);

	/* Operation on binary files */
	public:
		void ReadB(void* buffer, size_t bufferSize, size_t rSize);
		void WriteB(void* src, size_t srcSize);

	/* Public Operation on files */
	public:
		// Flush data
		void Flush();
		// Seek specify position
		bool Seek(size_t pos);
		// Get the current position
		UINT32 GetPosition();
		// Get the file length
		UINT32 GetLength();
		// Get the file Encoding type
		Encoding GetEncoding();
		// Is file open
		bool IsOpen();
		// Is file eof
		bool IsEof();

	protected:
		// File handle
		FILE* m_hFile;
		// *.txt Encoding
		Encoding m_encoding;

	protected:
		bool _OpenUTF8(wchar_t* fileName, wchar_t* openMode = _T("r+"));
		void _ReadLineUTF8(wstring& wStr, size_t maxSize);
		void _ReadUTF8();
		void _WriteLineUTF8(wstring& wStr);
		void _WriteUTF8(wstring& wStr);
	};
}

#endif